package com.xci.platform.web.core;

import com.xci.platform.auth.core.AuthHelper;
import com.xci.platform.auth.entity.LogEntity;
import com.xci.platform.auth.service.LogService;
import com.xci.platform.core.BoolMessage;
import com.xci.platform.helper.WebHelper;
import com.xci.platform.exception.ValidatorException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 全局异常拦截器
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 日志服务
     */
    @Resource
    private LogService logService;

    @Resource
    protected AuthHelper authHelper;

    /**
     * 全局异常拦截
     */
    @ExceptionHandler(value = Exception.class)
    public Object allExceptionHandler(HttpServletRequest request, Exception e) {
        //异常日志保存到数据库

        operateLog(request, e);
        boolean isAjax = (WebHelper.isAjax(request)||WebHelper.isApp(request));
        if (e instanceof MaxUploadSizeExceededException && isAjax) {
            //文件上传异常
            String msg = "文件大小不应大于" + ((MaxUploadSizeExceededException) e).getMaxUploadSize() / 1000 + "kb";
            return new BoolMessage(false, msg);
        } else if (e instanceof ValidatorException && isAjax) {
            //参数校验异常拦截
            ValidatorException ex = (ValidatorException) e;
            Map<String,String> errorMap =ex.getErrorMap();
            StringBuilder builder = new StringBuilder();
            for (String str:errorMap.values()){
                builder.append(str);
                builder.append(";");
            }
            return new BoolMessage<>(false, builder.toString(), errorMap);
        } else if (isAjax) {
            return new BoolMessage(false, e.getMessage());
        } else {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("exception", e);
            modelAndView.addObject("url", request.getRequestURL());
            modelAndView.setViewName("error/error500");
            return modelAndView;
        }
    }

    /**
     * 添加系统异常日志
     */
    private void operateLog(HttpServletRequest request, Exception e) {
        try {
            LogEntity entity = authHelper.buildExceptionLogInfo(request, e);
            logService.insert(entity);
        } catch (Exception ex) {
            log.error("全局异常日志保存到数据失败", ex);
        }
    }
}